from flask import Flask, request, jsonify, send_file
import os
import subprocess
from werkzeug.utils import secure_filename
from flask_cors import CORS
import logging # 引入日志模块
from typing import List
import glob

app = Flask(__name__)
CORS(app)  # 允许所有来源的跨域请求

# 配置日志
logging.basicConfig(level=logging.INFO) # 设置日志级别为INFO

# 确保这些路径对于Flask应用是正确且可访问的
UPLOAD_FOLDER = '/root/ruanJianGongCheng/data' # 上传文件存储目录
ANALYSIS_SCRIPT_PATH = '/root/sports/examples/soccer/main.py' # 分析脚本的路径

os.makedirs(UPLOAD_FOLDER, exist_ok=True) # 如果目录不存在则创建

# 修改 upload_video 函数
@app.route('/upload', methods=['POST'])
def upload_video():
    try:
        if 'video' not in request.files:
            app.logger.warning("请求中没有 'video' 文件部分")
            return jsonify({'error': '没有视频文件 (No video file part)'}), 400

        video_file = request.files['video']
        analysis_mode = request.form.get('mode', 'PITCH_DETECTION')
        
        if video_file.filename == '':
            app.logger.warning("未选择任何文件")
            return jsonify({'error': '未选择视频文件 (No selected file)'}), 400

        # 确保上传目录存在
        os.makedirs(UPLOAD_FOLDER, exist_ok=True)
        
        filename = secure_filename(video_file.filename)
        input_path = os.path.join(UPLOAD_FOLDER, filename)
        
        try:
            video_file.save(input_path)
            app.logger.info(f"文件已保存到: {input_path}")
        except Exception as e:
            app.logger.error(f"保存上传文件失败: {str(e)}")
            return jsonify({'error': f'保存文件失败: {str(e)}'}), 500

        # 构建输出文件名和路径
        base, ext = os.path.splitext(filename)
        output_filename = f"{base}-{analysis_mode.lower()}{ext}"
        output_path = os.path.join(UPLOAD_FOLDER, output_filename)

        # 构建分析命令
        try:
            cmd = [
                'python3', ANALYSIS_SCRIPT_PATH,
                '--source_video_path', input_path,
                '--target_video_path', output_path,
                '--device', 'cuda',
                '--mode', analysis_mode
            ]
            
            app.logger.info(f"执行分析命令: {' '.join(cmd)}")
            
            # 执行分析命令
            process_result = subprocess.run(
                cmd,
                capture_output=True,
                text=True,
                check=True,
                timeout=600  # 增加超时时间到10分钟
            )
            
            # 记录命令输出
            if process_result.stdout:
                app.logger.info(f"分析脚本输出: {process_result.stdout}")
            if process_result.stderr:
                app.logger.warning(f"分析脚本错误输出: {process_result.stderr}")

        except subprocess.TimeoutExpired as e:
            app.logger.error(f"分析超时: {str(e)}")
            cleanup_files(input_path)
            return jsonify({'error': '视频分析超时，请尝试较短的视频'}), 500
        except subprocess.CalledProcessError as e:
            app.logger.error(f"分析脚本执行失败: {str(e)}, 退出码: {e.returncode}")
            app.logger.error(f"错误输出: {e.stderr}")
            cleanup_files(input_path)
            return jsonify({'error': f'视频分析失败: {str(e)}'}), 500
        except Exception as e:
            app.logger.error(f"执行分析时发生错误: {str(e)}")
            cleanup_files(input_path)
            return jsonify({'error': f'视频分析过程出错: {str(e)}'}), 500

        # 清理原始文件
        try:
            if os.path.exists(input_path) and input_path != output_path:
                os.remove(input_path)
                app.logger.info(f"已删除原始文件: {input_path}")
        except Exception as e:
            app.logger.warning(f"清理原始文件失败: {str(e)}")

        # 检查输出文件是否存在
        if not os.path.exists(output_path):
            app.logger.error(f"分析完成但输出文件未找到: {output_path}")
            return jsonify({'error': '分析结果文件未生成'}), 500

        return jsonify({
            'message': '分析完成',
            'output_video_path': f'/result_video/{output_filename}'
        })

    except Exception as e:
        app.logger.error(f"处理上传请求时发生未预期的错误: {str(e)}", exc_info=True)
        return jsonify({'error': f'服务器处理出错: {str(e)}'}), 500

# 辅助函数：清理文件
def cleanup_files(*file_paths):
    """清理指定的文件"""
    for file_path in file_paths:
        try:
            if os.path.exists(file_path):
                os.remove(file_path)
                app.logger.info(f"已清理文件: {file_path}")
        except Exception as e:
            app.logger.warning(f"清理文件失败 {file_path}: {str(e)}")

# 添加健康检查端点
@app.route('/health', methods=['GET'])
def health_check():
    return jsonify({'status': 'ok'}), 200

@app.route('/result_video/<path:filename>')
def download_file(filename):
    """提供处理后视频的下载功能"""
    try:
        # 构建完整的文件路径
        file_path = os.path.join(UPLOAD_FOLDER, filename)
        
        # 检查文件是否存在
        if not os.path.exists(file_path):
            app.logger.error(f"请求的文件不存在: {file_path}")
            return jsonify({'error': '文件不存在'}), 404

        # 返回文件供下载
        return send_file(
            file_path,
            as_attachment=True,  # 这会触发浏览器的下载行为
            download_name=filename  # 指定下载时的文件名
        )
    except Exception as e:
        app.logger.error(f"下载文件时发生错误: {str(e)}")
        return jsonify({'error': f'文件下载失败: {str(e)}'}), 500

# 添加删除视频文件的路由
@app.route('/delete_videos', methods=['POST'])
def delete_videos():
    """删除分析视频文件"""
    try:
        data = request.get_json()
        if not data or 'filenames' not in data:
            app.logger.error("未提供文件名列表")
            return jsonify({'error': '未提供文件名列表'}), 400

        filenames = data['filenames']
        errors = []
        deleted_files = []

        for filename in filenames:
            try:
                # 只删除分析后的视频文件
                file_path = os.path.join(UPLOAD_FOLDER, filename)
                if os.path.exists(file_path):
                    os.remove(file_path)
                    deleted_files.append(filename)
                    app.logger.info(f"已删除分析文件: {file_path}")
                else:
                    app.logger.warning(f"分析文件不存在: {file_path}")
            except Exception as e:
                error_msg = f"删除分析文件 {filename} 失败: {str(e)}"
                app.logger.error(error_msg)
                errors.append(error_msg)

        return jsonify({
            'message': '删除操作完成',
            'deleted_files': deleted_files,
            'errors': errors
        })
    except Exception as e:
        app.logger.error(f"处理删除请求时发生错误: {str(e)}")
        return jsonify({'error': f'删除操作失败: {str(e)}'}), 500

# 配置详细的日志记录
if __name__ == '__main__':
    import logging
    logging.basicConfig(
        level=logging.DEBUG,
        format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
        handlers=[
            logging.StreamHandler(),
            logging.FileHandler('app.log')
        ]
    )
    app.run(host='0.0.0.0', port=5000)root@ed58f0c67214:~/ruanJianGongCheng/backend# 
